using System;
using System.Collections.Generic;
using System.Text;
using System.CodeDom;
using System.CodeDom.Compiler;
using System.Reflection;
using System.IO;
using CodeFactory.Library.Language;
using CodeFactory.Library.Config;

namespace CodeFactory.Library.CodeRunner
{
    public class Runner
    {
        private EncoderInfo coderInfo;
        private string codeText;

        public EncoderInfo CodeInfo
        {
            get { return this.coderInfo; }
            set { this.coderInfo = value; }
        }

        public string CodeText
        {
            get { return this.codeText; }
        }

        public Runner()
        {
            this.coderInfo = ConfigManager.Info.SysEncoder;
            this.codeText = string.Empty;
        }

        public Runner(EncoderInfo rcode)
        {
            this.coderInfo = rcode;
            this.codeText = string.Empty;
        }

        public object Run(string methodName, object[] paras)
        {
            RunnerMethod method = this.CreateMethod(methodName);
            return method.Run(paras);
        }

        public RunnerMethod CreateMethod(string methodName)
        {
            StreamReader sr = new StreamReader(ConfigManager.CurrentPath + "\\" + this.coderInfo.CodeFile);
            this.codeText = sr.ReadToEnd();
            sr.Close();
            CompilerParameters vCompilerParameters = new CompilerParameters();
            vCompilerParameters.GenerateExecutable = false;
            vCompilerParameters.GenerateInMemory = true;
            foreach (string s in this.coderInfo.AssemblieList)
            {
                vCompilerParameters.ReferencedAssemblies.Add(s);
            }
            CompilerResults vCompilerResults =
                CodeDomProvider.CreateProvider("CSharp").CompileAssemblyFromSource(vCompilerParameters, this.codeText);
            Assembly vAssembly = null;
            try
            {
                vAssembly = vCompilerResults.CompiledAssembly;
            }
            catch (Exception)
            {
                throw new Exception(LanguageManager.StringManager["Error_RunCode"]);
            }
            object vTemp = vAssembly.CreateInstance(this.coderInfo.ClassName);
            Type t = vTemp.GetType();
            MethodInfo method = vTemp.GetType().GetMethod(methodName);
            RunnerMethod m = new RunnerMethod();
            m.RunnerObject = vTemp;
            m.Method = method;
            return m;
        }
    }
}
